package com.first.run.security;

import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.first.run.constant.ConstantsConf;
import com.first.run.entity.SysPermission;
import com.first.run.entity.SysRole;
import com.first.run.entity.SysUser;
import com.first.run.service.SysPermissionService;
import com.first.run.service.SysRoleService;
import com.first.run.service.SysUserService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Component
@AllArgsConstructor
public class MyUserDetailsService implements UserDetailsService {

    private SysUserService userService;
    private SysRoleService roleService;
    private SysPermissionService permissionService;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
//        Cache cache = cacheManager.getCache(CacheConstants.USER_DETAILS);
//        if (cache != null && cache.get(username) != null) {
//            return (UserInfo) cache.get(username).get();
//        }

        /**
         * 根据用户名查询用户信息
         */
//        SysUser sysUser = userService.findSysUserByUserName(username);
        SysUser sysUser = userService.getOne(Wrappers.<SysUser>query().lambda().eq(SysUser::getUsername, username));
        if(null == sysUser){
            throw new UsernameNotFoundException("用户不存在");
        }

        UserDetails userDetails = getUserDetails(sysUser);

        System.out.println("userDetails = " + JSON.toJSONString(userDetails));

//        cache.put(username, userDetails);
        // 构造security用户
        return  userDetails;
    }

    /**
     * 得到用户信息
     * @param sysUser
     * @return
     */
    private UserDetails getUserDetails(SysUser sysUser){
        System.out.println("getUserDetails::::查询用户信息");
        System.out.println("sysUser::"+ sysUser.getUsername());
        System.out.println("sysUSEr:password:::"+sysUser.getPassword());
        //查询角色列表  （ID）
        List<Integer> roleIds = roleService.findRolesByUserId(sysUser.getUserId())
                .stream()
                .map(SysRole::getRoleId)
                .collect(Collectors.toList());

        //授权集合
        Set<String> dbAuthsSet = new HashSet<>();
        Set<String> permissions = new HashSet<>();
        if (ArrayUtil.isNotEmpty(ArrayUtil.toArray(roleIds, Integer.class))) {
            // 获取角色
            Arrays.stream(ArrayUtil.toArray(roleIds, Integer.class)).forEach(role -> dbAuthsSet.add(SecurityConstant.ROLE + role));
            //设置权限列表（menu.permission）
            roleIds.forEach(roleId -> {
                List<String> permissionList = permissionService.listPermissionByRoleId(roleId)
                        .stream()
                        .filter(permission -> StringUtils.isNotEmpty(permission.getPermission()))
                        .map(SysPermission::getPermission)
                        .collect(Collectors.toList());
                permissions.addAll(permissionList);
            });

            // 获取权限
            dbAuthsSet.addAll(Arrays.asList(ArrayUtil.toArray(permissions, String.class)));
        }

        Collection<? extends GrantedAuthority> authorities = AuthorityUtils.createAuthorityList(dbAuthsSet.toArray(new String[0]));

        return new UserInfo(sysUser.getUserId(), sysUser.getUsername(), SecurityConstant.BCRYPT + sysUser.getPassword(),
                StrUtil.equals(sysUser.getLockFlag(), ConstantsConf.STATUS_NORMAL), true, true, true, authorities);
    }

}
